<?php
/************************
 *  Codenova.pl Project
 *  Created by: Kamil Mrzygłód
 *
 *  (c) 2013 by Codenova.pl
 *  All Right Reserved
 ***********************/

namespace Gotcha\App\Extensions;

// Gotcha routing class

use Gotcha\App\Types\String;

class GotchaRoutingExtension extends GotchaFileSystemExtension {
    // Routes
    private $routes = array();

    // Current request
    public $routing_current_request;

    public function __construct() {
        if (isset($_SERVER['PATH_INFO'])) {
            $this->routing_current_request = $_SERVER['PATH_INFO'];
        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
            $this->routing_current_request = $_SERVER['ORIG_PATH_INFO'];
        } else {
            $this->routing_current_request = '/';
        }
    }

    public function __toString() {
        return (string)$this->routing_current_request;
    }

    public function processRequest(String $file) {
        $this->routes = parent::processRoutesFile($file);

        // Check if route exists
        if (array_key_exists($this->routing_current_request, $this->routes)) {
            if (parent::CheckDirExistence(new String('Modules/'.$this->routes[$this->routing_current_request]['module'])) === true) {
                // Module exists, search for given controller
                if (parent::CheckFileExistence(new String($this->routes[$this->routing_current_request]['controller'].'Controller.php'), new String('Modules/'.$this->routes[$this->routing_current_request]['module'].'/Controllers/')) === true) {
                    // Controller exists, we can load a file
                    require_once 'Modules/'.$this->routes[$this->routing_current_request]['module'].'/Controllers/'.$this->routes[$this->routing_current_request]['controller'].'Controller.php';

                    // We use invoke on reflection method to get its results
                    try {
                        // We hardcoded place from each module starts.
                        // It's more an MVC idea but to keep code and
                        // module logic clean, we are forcing storing
                        // all controllers in Modules/[MODULE_NAME]/Controllers
                        // dir.
                        $reflection_method = new \ReflectionMethod('Modules\\'.$this->routes[$this->routing_current_request]['module'].'\Controllers\\'.$this->routes[$this->routing_current_request]['controller'].'Controller', $this->routes[$this->routing_current_request]['action']);
                    } catch (\Exception $e) {
                        GotchaLogsExtension::createNewLogEntry(new String($e->getTraceAsString()));
                        GotchaErrorsExtension::throwError(new String(GotchaCulturesExtension::getTranslation(new String('CLASS_OR_METHOD_INITIALIZATION_ERROR'))));
                        exit;
                    }

                    // Invoke method linked with controller
                    $class_name = 'Modules\\'.$this->routes[$this->routing_current_request]['module'].'\Controllers\\'.$this->routes[$this->routing_current_request]['controller'].'Controller';
                    echo $reflection_method->invoke(new $class_name(), null);

                    return true;
                } else {
                    // Controller does not exist
                    self::header404();
                }
            } else {
                // Module does not exist
                self::header404();
            }
        }
        self::header404();
    }

    private function header404() {
        // Set 404 header
        header('HTTP/1.0 404 Not Found');
        require_once GOTCHA_ROOT_DIR.'/App/Templates/Errors/404.phtml';
        exit;
    }
}